import unittest

from os import path

from lsup_rdf import env_init, term, triple, graph
from lsup_rdf.term import IRIRef, Literal, BNode

TEST_DIR = path.realpath(path.dirname(__file__))


class TestTerm(unittest.TestCase):
    def setUp(self):
        self.s1 = IRIRef("urn:s:1")
        self.p1 = IRIRef("urn:p:1")
        self.o1 = IRIRef("urn:o:1")
        self.s2 = IRIRef("urn:s:2")
        self.p2 = IRIRef("urn:p:2")
        self.o2 = IRIRef("urn:o:2")
        self.s3 = IRIRef("urn:s:3")
        self.p3 = IRIRef("urn:p:3")
        self.o3 = IRIRef("urn:o:3")

        self.trp = [
            triple.Triple(self.s1, self.p1, self.o1),
            triple.Triple(self.s2, self.p2, self.o2),
        ]
        self.t3 = triple.Triple(self.s3, self.p3, self.o3)
        self.t4 = triple.Triple(self.s1, self.p1, self.o1)

    def test_iriref(self):
        uri = IRIRef("urn:s:1")

        self.assertTrue(isinstance(uri, term.Term))
        self.assertEqual(uri.data, 'urn:s:1')
        self.assertEqual(uri._type, term.TERM_IRIREF)
        self.assertFalse(hasattr(uri, 'datatype'))
        self.assertFalse(hasattr(uri, 'lang'))

    def test_literal(self):
        lit = Literal('Hello')

        self.assertTrue(isinstance(lit, term.Term))
        self.assertEqual(lit.data, 'Hello')
        self.assertEqual(lit._type, term.TERM_LITERAL)
        self.assertEqual(
                lit.datatype.data, 'http://www.w3.org/2001/XMLSchema#string')
        self.assertTrue(lit.lang is None)

    def test_lt_literal(self):
        lt_lit = Literal('Hola', lang='es-ES')

        self.assertTrue(isinstance(lt_lit, term.Term))
        self.assertEqual(lt_lit.data, 'Hola')
        self.assertEqual(lt_lit._type, term.TERM_LT_LITERAL)
        self.assertEqual(
            lt_lit.datatype.data, 'http://www.w3.org/2001/XMLSchema#string'
        )
        self.assertEqual(lt_lit.lang, 'es-ES')

    def test_bnode(self):
        bn = BNode('1234')

        self.assertTrue(isinstance(bn, term.Term))
        self.assertEqual(bn.data, '1234')
        self.assertEqual(bn._type, term.TERM_BNODE)
        self.assertFalse(hasattr(bn, 'datatype'))
        self.assertFalse(hasattr(bn, 'lang'))

    def test_graph(self):
        gr = graph.Graph(graph.STORE_HTABLE)
        gr.uri = term.Term(term.TERM_IRIREF, 'urn:c:1')

        self.assertEqual(gr.uri, 'urn:c:1')

    def test_graph_ops(self):
        gr = graph.Graph(graph.STORE_HTABLE)

        print('Adding triples.')
        gr.add(self.trp)

        self.assertEqual(len(gr), 2)
        self.assertTrue(self.trp[0] in gr)
        self.assertTrue(self.trp[1] in gr)
        self.assertFalse(self.t3 in gr)
        self.assertTrue(self.t4 in gr)

        gr.remove(self.s1, None, None)

        self.assertFalse(self.trp[0] in gr)
        self.assertTrue(self.trp[1] in gr)

        print('Encoded NT:')
        for line in gr.to_rdf('nt'):
            print(line)

    def test_deserialize(self):
        print('From file.')
        with open(path.join(TEST_DIR, 'assets', 'test.nt'), 'rb') as fh:
            gr2 = graph.Graph.from_rdf(fh, 'nt')

        self.assertTrue(self.trp[0] in gr2)
        self.assertTrue(self.trp[1] in gr2)


if __name__ == '__main__':
    env_init()
    unittest.main()
